// 解决Promise 的异步问题

// 目标：Promise 是一个类，在执行这个类的时候会传入一个执行器，这个执行器会立即执行
// Promise 会有三种状态

// Pending 等待
// Fulfilled 完成
// Rejected 失败


// 状态只能由 Pending --> Fulfilled 或者 Pending --> Rejected，且一但发生改变便不可二次修改；
// Promise 中使用 resolve 和 reject 两个函数来更改状态；
// then 方法内部做但事情就是状态判断

// 如果状态是成功，调用成功回调函数
// 如果状态是失败，调用失败回调函数

// 思路：当存在异步任务时候，同步任务进入.then,此时因为resolve , reject 在异步任务，状态还没改变仍然未 pending 
//    新增属性 onFulfilledCallback， onRejectedCallback 储存回调函数,等到异步任务时间到后，在调用储存的回调函数，执行.then里面的成功，失败回调


const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECT = 'reject'

class MyPromise2 {
    constructor(executor) {
        executor(this.resolve, this.reject)
    }

    status = PENDING;

    value = null;

    reason = null;

    // 储存成功的回调函数   用于异步操作
    onFulfilledCallback = null;

    // 储存失败的回调函数 
    onRejectedCallback = null;

    resolve = (value) => {
        if (this.status === PENDING) {
            this.status = FULFILLED;
            this.value = value;

            //---------------------------
            //  判断成功回调是否存在，如果存在就调用
            this.onFulfilledCallback && this.onFulfilledCallback(value);
        }
    }

    reject = (reason) => {
        if (this.status === PENDING) {
            this.status = REJECT;
            this.reason = reason;

            // ------------------------------
            // 判断失败回调是否存在，如果存在就调用
            this.onRejectedCallback && this.onRejectedCallback(reason)
        }
    }


    then(onFulfilled, onRejected) {

        if (this.status === FULFILLED) {
            onFulfilled(this.value)
        } else if (this.status === REJECT) {
            onRejected(this.reason);
        } else if (this.status === PENDING) {  // .then 时候状态还为 PENDING 表示还没有执行resolve , reject 因为此时是异步的
            // 因为不知道后面状态的变化情况，所以将成功回调和失败回调存储起来
            // 等到执行成功失败函数的时候再传递
            this.onFulfilledCallback = onFulfilled;  // 将.then 要执行的函数储存起来，等待异步操作完成再执行
            this.onRejectedCallback = onRejected;

        }
    }

}

// 没有打印信息！！！

// const promise = new MyPromise2((resolve, reject) => {
//     setTimeout(() => {
//         resolve('success')
//     }, 2000);
// })

// promise.then(value => {
//     console.log('resolve', value)
// }, reason => {
//     console.log('reject', reason)
// })


module.export = MyPromise2
